﻿using Autodesk.AutoCAD.Colors;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HPDI.DrawingStandard
{
    public static class PLPloter
    {
        /// <summary>
        /// 添加多线
        /// </summary>
        /// <param name="sp"></param>
        /// <param name="ep"></param>
        /// <param name="layerName">图层名称</param>
        /// <param name="dx0">起点X偏移</param>
        /// <param name="dy0">起点X偏移</param>
        /// <param name="dx1">终点X偏移</param>
        /// <param name="dy1">终点Y偏移</param>
        /// <param name="num"></param>
        /// <returns></returns>
        public static DBObjectCollection AddPolyline(Point2d sp, Point2d ep, string layerName, double dx0=0, double dy0=0, double dx1=0, double dy1=0)
        {
            DBObjectCollection res = new DBObjectCollection();
            Database db = HostApplicationServices.WorkingDatabase;
            Polyline line = new Polyline() { Closed = false, Layer = layerName, Plinegen=true };//定义不封闭的Polyline
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable blockTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord recorder = tr.GetObject(blockTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
              
                line.AddVertexAt(0, sp.C2D(dx0, dy0), 0, 0, 0);
                line.AddVertexAt(1, ep.C2D(dx1, dy1), 0, 0, 0);

                res.Add(line);
            }
            return res;
        }

        /// <summary>
        /// 创建多线
        /// </summary>
        /// <param name="stPoint">起点</param>
        /// <param name="endPoint">终点</param>
        /// <param name="layer">图层</param>
        /// <returns></returns>
        public static DBObjectCollection AddPolyline( Point2d stPoint, Point2d endPoint, string layer)
        {
            DBObjectCollection res = new DBObjectCollection();
            Database db = HostApplicationServices.WorkingDatabase;
            Polyline line = new Polyline() { Layer = layer, Plinegen = true };
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable blockTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord modelSpace = tr.GetObject(blockTbl[BlockTableRecord.ModelSpace],
                    OpenMode.ForWrite) as BlockTableRecord;
                TextStyleTable st = tr.GetObject(db.TextStyleTableId, OpenMode.ForRead) as TextStyleTable;

                line.AddVertexAt(0, stPoint.C2D(), 0, 0, 0);
                line.AddVertexAt(1, endPoint.C2D(), 0, 0, 0);
                line.LineWeight = Autodesk.AutoCAD.DatabaseServices.LineWeight.ByLayer;

                res.Add(line);
            }
            return res;
        }

        /// <summary>
        /// 根据点集合绘制多线
        /// </summary>
        /// <param name="ptList">点集合</param>
        /// <param name="layerName">图层名称</param>
        /// <param name="isClose">是否闭合，默认不闭合</param>
        /// <returns></returns>
        public static DBObjectCollection AddPolylineByPointList( List<Point2d> ptList, string layerName, bool isClose)
        {
            DBObjectCollection res = new DBObjectCollection();
            Database db = HostApplicationServices.WorkingDatabase;
            Polyline line = new Polyline() { Closed = isClose, Layer = layerName, Plinegen = true };//定义不封闭的Polyline
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable blockTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord recorder = tr.GetObject(blockTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

              
                for (int i = 0; i < ptList.Count; i++)
                {
                    line.AddVertexAt(i, ptList[i], 0, 0, 0);
                }
                res.Add(line);
            }
            return res;
        }

        /// <summary>
        /// 八边形绘图
        /// </summary>
        /// <param name="AnchorPoint">锚点，八边形下中心点</param>
        /// <param name="Height">总高</param>
        /// <param name="Width">总宽</param>
        /// <param name="F1x">下倒角，x方向</param>
        /// <param name="F1y">下倒角，y方向</param>
        /// <param name="F2x">上倒角，x方向</param>
        /// <param name="F2y">上倒角，y方向</param>
        /// <param name="layer">图层</param>
        public static DBObjectCollection AddPoly8(Point2d AnchorPoint, double Height, double Width,
             string layer,double F1x = 50, double F1y = 50, double F2x = 50, double F2y = 50)
        {
            DBObjectCollection res = new DBObjectCollection();
            Database db = HostApplicationServices.WorkingDatabase;
            Polyline PL1 = new Polyline() { Closed = true, Layer = layer, Plinegen = true };
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                TextStyleTable st = tr.GetObject(db.TextStyleTableId, OpenMode.ForRead) as TextStyleTable;
                BlockTable blockTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord recorder;
                recorder = tr.GetObject(blockTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

                Line2d AxisY = new Line2d(AnchorPoint, AnchorPoint.C2D(0, 1));
                Point2d p0, p1, p2, p3, p4, p5, p6, p7;

                p0 = AnchorPoint.C2D(-0.5 * Width + F1x, 0);
                p1 = p0.Mirror(AxisY);
                p2 = p1.C2D(F1x, -F1y);
                p3 = p2.C2D(0, -Height +F1y +F2y);
                p4 = p3.C2D(-F2x, -F2y);
                p5 = p4.Mirror(AxisY);
                p6 = p3.Mirror(AxisY);
                p7 = p2.Mirror(AxisY);
                PL1.AddVertexAt(0, p0, 0, 0, 0);
                PL1.AddVertexAt(1, p1, 0, 0, 0);
                PL1.AddVertexAt(2, p2, 0, 0, 0);
                PL1.AddVertexAt(3, p3, 0, 0, 0);
                PL1.AddVertexAt(4, p4, 0, 0, 0);
                PL1.AddVertexAt(5, p5, 0, 0, 0);
                PL1.AddVertexAt(6, p6, 0, 0, 0);
                PL1.AddVertexAt(7, p7, 0, 0, 0);
                res.Add(PL1);
            }
            return res;
        }

        /// <summary>
        /// 添加四角圆弧多边形
        /// </summary>
        /// <param name="AnchorPoint">插入点</param>
        /// <param name="Height">高</param>
        /// <param name="Width">宽</param>
        /// <param name="layer">图层</param>
        /// <param name="ArcR">圆弧半径</param>
        /// <returns></returns>
        public static DBObjectCollection AddArcPoly(Point2d AnchorPoint, double Height, double Width,
          string layer, double ArcR = 50)
        {
            DBObjectCollection res = new DBObjectCollection();
            Database db = HostApplicationServices.WorkingDatabase;
            Polyline PL1 = new Polyline() { Closed = true, Layer = layer, Plinegen = true };
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                TextStyleTable st = tr.GetObject(db.TextStyleTableId, OpenMode.ForRead) as TextStyleTable;
                BlockTable blockTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord recorder;
                recorder = tr.GetObject(blockTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

                Line2d AxisY = new Line2d(AnchorPoint, AnchorPoint.C2D(0, 1));
                Point2d p0, p1, p2, p3, p4, p5, p6, p7;

                p0 = AnchorPoint.C2D(-0.5 * Width + ArcR, 0);
                p1 = p0.Mirror(AxisY);
                p2 = p1.C2D(ArcR, -ArcR);
                p3 = p2.C2D(0, -Height + ArcR + ArcR);
                p4 = p3.C2D(-ArcR, -ArcR);
                p5 = p4.Mirror(AxisY);
                p6 = p3.Mirror(AxisY);
                p7 = p2.Mirror(AxisY);
                var res1 = AddLine(p0, p1,layer);
                res.Add(res1);
                res1 = AddLine(p2, p3, layer);
                res.Add(res1);
                res1 = AddLine(p4, p5, layer);
                res.Add(res1);
                res1 = AddLine(p6, p7, layer);
                res.Add(res1);
                Arc arc2 = new Arc(p0.C3D(0, -ArcR), ArcR, GeTools.DegreeToRadian(90), GeTools.DegreeToRadian(90 + 90)) { Layer = layer };
                res.Add(arc2);
                arc2 = new Arc(p1.C3D(0, -ArcR), ArcR, GeTools.DegreeToRadian(90 - 90), GeTools.DegreeToRadian(90)) { Layer = layer };
                res.Add(arc2);
                arc2 = new Arc(p4.C3D(0, ArcR), ArcR, GeTools.DegreeToRadian(-90), GeTools.DegreeToRadian(-90 + 90)) { Layer = layer };
                res.Add(arc2);
                arc2 = new Arc(p5.C3D(0, ArcR), ArcR, GeTools.DegreeToRadian(-90 - 90), GeTools.DegreeToRadian(-90 )) { Layer = layer };
                res.Add(arc2);
            }
            return res;
        }

        /// <summary>
        /// 绘制四边形
        /// </summary>
        /// <param name="db"></param>
        /// <param name="ext"></param>
        /// <param name="upcenter"></param>
        /// <param name="wl"></param>
        /// <param name="wr"></param>
        /// <param name="h"></param>
        /// <param name="layer"></param>
        /// <param name="isDrawing"></param>
        /// <returns></returns>
        public static DBObjectCollection AddPloy4(  Point2d upcenter, double wl, double wr, double h, string layer)
        {
            DBObjectCollection res = new DBObjectCollection();
            Database db = HostApplicationServices.WorkingDatabase;
            Polyline PL1 = new Polyline() { Closed = true, Layer = layer, Plinegen = true };
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                TextStyleTable st = tr.GetObject(db.TextStyleTableId, OpenMode.ForRead) as TextStyleTable;
                BlockTable blockTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord recorder;
                recorder = tr.GetObject(blockTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

                Point2d ptop, pbot;
                Point2d p11, p12, p13, p14;
                ptop = upcenter;
                pbot = upcenter.C2D(0, -h);
                p11 = ptop.C2D(-wl);
                p12 = pbot.C2D(-wl);
                p13 = ptop.C2D(wr);
                p14 = pbot.C2D(wr);
                PL1.AddVertexAt(0, p12, 0, 0, 0);
                PL1.AddVertexAt(1, pbot, 0, 0, 0);
                PL1.AddVertexAt(2, p14, 0, 0, 0);

                PL1.AddVertexAt(3, p13, 0, 0, 0);
                PL1.AddVertexAt(4, ptop, 0, 0, 0);
                PL1.AddVertexAt(5, p11, 0, 0, 0);

                res.Add(PL1);
            }
            return res;
        }

       
        /// <summary>
        /// 绘制实心圆
        /// </summary>
        /// <param name="pt">圆点</param>
        /// <param name="radius">半径</param>
        /// <returns></returns>
        public static DBObjectCollection AddSolidCircle(Point2d pt, double radius,string layerName= "H标注")
        {
            DBObjectCollection res = new DBObjectCollection();
            Database db = HostApplicationServices.WorkingDatabase;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                TextStyleTable st = tr.GetObject(db.TextStyleTableId, OpenMode.ForRead) as TextStyleTable;
                BlockTable blockTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord recorder = tr.GetObject(blockTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
                Circle circle = new Circle(pt.C3D(), Vector3d.ZAxis, radius) { Layer = layerName };
                circle.SetDatabaseDefaults();//默认参数

                res.Add(circle);
                // 添加圆到一个 ObjectID 数组中去 
                ObjectIdCollection acObjIdColl = new ObjectIdCollection();
                acObjIdColl.Add(circle.ObjectId);

                // 创建图案填充对象并添加到块表记录中   
                Hatch hatch = new Hatch();
                hatch.Layer=layerName;

                hatch.SetDatabaseDefaults();
                hatch.SetHatchPattern(HatchPatternType.PreDefined, "SOLID"); //设置填充图案
                hatch.Associative = true;
                hatch.AppendLoop(HatchLoopTypes.Outermost, acObjIdColl);
                hatch.EvaluateHatch(true);
                res.Add(hatch);
            }
            return res;
        }
       
        public static DBObjectCollection AddCircle(Point2d pt, double radius, string layerName = "H标注")
        {
            DBObjectCollection res = new DBObjectCollection();
            Database db = HostApplicationServices.WorkingDatabase;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                TextStyleTable st = tr.GetObject(db.TextStyleTableId, OpenMode.ForRead) as TextStyleTable;
                BlockTable blockTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord recorder = tr.GetObject(blockTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
                Circle circle = new Circle(pt.C3D(), Vector3d.ZAxis, radius) { Layer = layerName };
                circle.SetDatabaseDefaults();//默认参数
                res.Add(circle);
               
            }
            return res;
        }

        /// <summary>
        /// 添加Line线
        /// </summary>
        /// <param name="db"></param>
        /// <param name="ext"></param>
        /// <param name="stPoint"></param>
        /// <param name="endPoint"></param>
        /// <param name="layer"></param>
        /// <returns></returns>

        public static DBObjectCollection AddLine( Point2d stPoint, Point2d endPoint, string layer)
        {
            DBObjectCollection res = new DBObjectCollection();
            Database db = HostApplicationServices.WorkingDatabase;
            Line line = new Line(stPoint.C3D(), endPoint.C3D());
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable blockTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord modelSpace = tr.GetObject(blockTbl[BlockTableRecord.ModelSpace],
                    OpenMode.ForWrite) as BlockTableRecord;
                TextStyleTable st = tr.GetObject(db.TextStyleTableId, OpenMode.ForRead) as TextStyleTable;
                line.Layer = layer;

                res.Add(line);
            }
            return res;
        }


        public static DBObjectCollection AddUpperArcBreakLine( Point2d pt, double L = 100 ,string Layer="H细线")
        {
            Database db = HostApplicationServices.WorkingDatabase;
            DBObjectCollection res = new DBObjectCollection();
            double arcRadius = L * 0.5;
            #region      
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                #region  圆弧
             
                TextStyleTable st = tr.GetObject(db.TextStyleTableId, OpenMode.ForRead) as TextStyleTable;
                BlockTable blockTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord recorder = tr.GetObject(blockTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

                double arcAngle = 60;

                Arc arc1 = new Arc(pt.C3D(-arcRadius + arcRadius * Math.Sin(GeTools.DegreeToRadian(arcAngle / 2)),  arcRadius * Math.Cos(GeTools.DegreeToRadian(arcAngle / 2))),
                    arcRadius, GeTools.DegreeToRadian(240), GeTools.DegreeToRadian(240 + arcAngle))
                { Layer = Layer };
                res.Add(arc1);

                Arc arc2 = new Arc(pt.C3D((arcRadius * Math.Sin(GeTools.DegreeToRadian(arcAngle / 2))), -(arcRadius * Math.Cos(GeTools.DegreeToRadian(arcAngle / 2)))),
                    arcRadius, GeTools.DegreeToRadian(60), GeTools.DegreeToRadian(60 + arcAngle))
                { Layer = Layer };

                res.Add(arc2);

                Arc arc3 = new Arc(pt.C3D((arcRadius * Math.Sin(GeTools.DegreeToRadian(arcAngle / 2))), arcRadius * Math.Cos(GeTools.DegreeToRadian(arcAngle / 2))),
                    arcRadius, GeTools.DegreeToRadian(240), GeTools.DegreeToRadian(240 + arcAngle))
                { Layer = Layer };

                res.Add(arc3);
                #endregion
            }
            #endregion
            return res;
        }
        public static DBObjectCollection AddBottomArcBreakLine(Point2d pt, double L = 100,string Layer = "H细线")
        {
            Database db = HostApplicationServices.WorkingDatabase;
            DBObjectCollection res = new DBObjectCollection();
            #region 
            double arcRadius = L* 0.5;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                Point3dCollection pts = new Point3dCollection();
                TextStyleTable st = tr.GetObject(db.TextStyleTableId, OpenMode.ForRead) as TextStyleTable;
                BlockTable blockTbl = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord recorder = tr.GetObject(blockTbl[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
                #region  圆弧
                double arcAngle = 60;
                double cosH = arcRadius * Math.Cos(GeTools.DegreeToRadian(arcAngle / 2));
                // 绘制弧线
                Arc arc1 = new Arc(pt.C3D(-arcRadius + arcRadius / 2, -cosH), arcRadius, GeTools.DegreeToRadian(60), GeTools.DegreeToRadian(60 + arcAngle)) { Layer = Layer };

                res.Add(arc1);


                Arc arc2 = new Arc(pt.C3D((arcRadius / 2), -cosH), arcRadius, GeTools.DegreeToRadian(60), GeTools.DegreeToRadian(60 + arcAngle)) { Layer = Layer };

                res.Add(arc2);


                Arc arc3 = new Arc(pt.C3D(-arcRadius + arcRadius / 2, cosH), arcRadius, GeTools.DegreeToRadian(240), GeTools.DegreeToRadian(240 + arcAngle)) { Layer = Layer };

                res.Add(arc3);

                #endregion
            }
            #endregion
            return res;
        }
    }


    public enum ArrowDirection
    {
        East,//东方      右
        West, //西方     左
        North ,// 北方   上
        South, //南方    下
    }

    public enum eDirection
    {
        E_LEFT,
        E_RIGHT,
        E_TOP,
        E_BOTTOM
    }

    public enum eArrow
    {
        E_ARROW_NULL,                   // 无箭头
        E_ARROW_LEFT_ARROW,             // 左边箭头
        E_ARROW_RIGHT_ARROW,            // 左边箭头
        E_ARROW_DOUBLE_SIDE_ARROW,      // 双向箭头
    }
}
